package org.springblade.modules.digitalization.utils;


import cn.hutool.core.codec.Base64;
import com.google.common.collect.Maps;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class QrUtils {
    public static void main(String[] args) throws IOException, DocumentException {
        List<String> users = new ArrayList<>();
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        users.add("张三@a5c8a5e8-df2b-4706-bea4-08d0939410e3");
        createPDf(users, "2");
    }

    /**
     * @param users
     * @param mode  1 条形码  其他二维码
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static byte[] createPDf(List<String> users, String mode) throws IOException, DocumentException {
        String path = "C:/WINDOWS/Fonts/simhei.ttf";
        Font font = FontFactory.getFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, 8f, Font.NORMAL, BaseColor.BLACK);

        final Document document = new Document();
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        final PdfWriter instance = PdfWriter.getInstance(document, byteArrayOutputStream);
//        final PdfWriter instance = PdfWriter.getInstance(document, new FileOutputStream("D:/1.pdf"));
        document.open();
        int minSize = 6;
        if (mode.equals("1")) {
            minSize = 3;
        }
        int column = Math.min(users.size(), minSize);
        PdfPTable table = new PdfPTable(column);
        table.setWidthPercentage(100);
        table.setHeaderRows(0);
        table.setFooterRows(0);
        List<PdfPRow> rows1 = table.getRows();
        float[] columnWidths = new float[column];
        for (int i = 0; i < columnWidths.length; i++) {
            columnWidths[i] = 100f;
        }
        table.setWidths(columnWidths);
        table.setSpacingAfter(0);
        table.setSpacingBefore(0);
        PdfPCell[] cells = null;
        PdfPCell[] cells2 = null;
        for (int i = 0; i < users.size(); i++) {
            if (i % column == 0) {
                cells = new PdfPCell[column];
                cells2 = new PdfPCell[column];
                PdfPRow rows = new PdfPRow(cells);
                PdfPRow rows2 = new PdfPRow(cells2);
                rows1.add(rows);
                rows1.add(rows2);
            }
            String s = users.get(i);
            final String[] split = s.split("@");
            String code = "";
            if (mode.equals("1")) {
                code = new StringBuilder().append(split[0]).append('-').append(split[1]).toString();
            } else {
                code = new StringBuilder().append(split[1]).append('\n').append(split[0]).toString();
            }
            int j = i % minSize;
            if (mode.equals("1")) {
                cells[j] = new PdfPCell(Image.getInstance(getBarcode(split[2])));
            } else {
                cells[j] = new PdfPCell(Image.getInstance(geterBarcode(Base64.encode(s))));
            }
            cells[j].setBorder(BaseColor.BLACK.getBlue());
            cells[j].setPadding(0);
            cells[j].setPaddingBottom(0);
            cells[j].setPaddingTop(0);

            cells[j].setHorizontalAlignment(Element.ALIGN_CENTER);
            cells[j].setVerticalAlignment(Element.ALIGN_CENTER);
            cells2[j] = new PdfPCell(new Paragraph(code, font));
            cells2[j].setBorder(BaseColor.BLACK.getBlue());
            cells2[j].setPaddingBottom(1);
            cells2[j].setPaddingTop(0);
            cells2[j].setMinimumHeight(0);
            cells2[j].setHorizontalAlignment(Element.ALIGN_CENTER);
            cells2[j].setVerticalAlignment(Element.ALIGN_CENTER);
        }
        document.add(table);
        document.close();
        instance.close();
        return byteArrayOutputStream.toByteArray();

    }

    public static String getBase64ErCode(String string) {
        return  Base64.encode(geterBarcode(string));
//        return "data:image/png;base64," + Base64.encode(geterBarcode(string));
    }

    public static String getBase64BarCode(String string) {
        /* Try to encode the string as a barcode */
        return  Base64.encode(getBarcode(string));
//        return "data:image/png;base64," + Base64.encode(getBarcode(string));
    }

    public static byte[] getBarcode(String string) {
        /* Try to encode the string as a barcode */
        try {
            Code128Writer writer = new Code128Writer();
            Map<EncodeHintType,Object> hind= Maps.newHashMap();
            hind.put(EncodeHintType.MARGIN,2);
            BitMatrix bar = writer.encode(new String(string.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), BarcodeFormat.CODE_128, 150, 30, hind);
            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bar, "png", byteArrayOutputStream);
            final byte[] bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();
            return bytes;
        } catch (WriterException | IOException e) {
            throw new RuntimeException(e);
        }
    }
	public static InputStream getBarcodeToInputStream(String string) {
		/* Try to encode the string as a barcode */
		try {
			int width = 300;
			int height = 300;
			String format = "png";
			Map<EncodeHintType, Object> hints = new HashMap<>();
			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
			BitMatrix bitMatrix = new MultiFormatWriter().encode(string, BarcodeFormat.QR_CODE, width, height, hints);
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			MatrixToImageWriter.writeToStream(bitMatrix, format, outputStream);
			return  new ByteArrayInputStream(outputStream.toByteArray());
		} catch (WriterException | IOException e) {
			throw new RuntimeException(e);
		}
	}

    public static byte[] geterBarcode(String content) {
        try {
            Writer writer = new QRCodeWriter();
            Map<EncodeHintType,Object> hind= Maps.newHashMap();
            hind.put(EncodeHintType.MARGIN,1);
            hind.put(EncodeHintType.CHARACTER_SET,"utf-8");
            hind.put(EncodeHintType.PDF417_COMPACT,true);
            BitMatrix bar = writer.encode(new String(content.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), BarcodeFormat.QR_CODE, 100, 100,hind);
            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bar, "png", byteArrayOutputStream);
            final byte[] bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();
            return bytes;
        } catch (WriterException | IOException e) {
            throw new RuntimeException(e);
        }
    }
}
